<template>
	<view class="content">
		<autosearch :mapData="markers" @asyncData="asyncData"></autosearch>
	　　<view class='map'>
			 <map
			  v-if="map_state"
			 class="map_container" 
			 id="map" 
			 :longitude="longitude" 
			 :latitude="latitude" 
			 :scale="scale" 
			 :markers="markers" 
			 :include-points='markers'
			 :clusterId='3'
			 :enable-poi='true'
			 :show-compass="true"
			 @regionchange="regionchange"
			 @markertap="makertap">
			 </map>
		</view>
		<view class="map_text">
			 <canvas :style="{ width: canvasW + 'rpx', height: canvasH + 'rpx' }" canvas-id="myCanvas" id="myCanvas"></canvas>
		</view>
	　　<view class="details">
				<view>设备名：{{equipMentname}}</view>
		</view>
	</view>
</template>

<script>
	import autosearch from '../../myComponent/autosearch/index.vue'//模糊搜索组件
	import Canvasmap from '@/myclass/canvasmap.js'
	import tableData from './tableData.js' 
	import province from './province.js'
	var amapFile = require('@/js_sdk/gaode_map/amap-wx.js');
	export default {
		name:'grant', 
		components:{
			autosearch
		},
		data() {
			return {
				map_state:true,//控制搜索是从新渲染组件
				markers: [],
				latitude: '',
				longitude: '',
				equipMentname:'',
				list:tableData,
				on_id:34,//设置默认显示标记信息，怎么传进来看自己需求
				canvasW:64, // 画布宽
				canvasH:64, // 画布高
				img:'',
				canvas_map:null,
				map_scale:5,
				scale:19,
				markers_id:[],
				province:province
			}
		},
		 async onLoad() {
			 //this.Variable.data使用外部定义的全局对象，因为对比在当前组件里面进行数据交互和全局对象交互效率相差10倍不止
			var ad=[]
			this.Variable.data=tableData
			var beginTime = +new Date(); 
			
			/*
			模拟省市数据开始，提前处理好省市数据，正确做法应该项后台请求当前每个省份和市级标点数量，（提升效率1）
			*/
			for (var i =0; i < 20; i++) { 
			  var latitude = this.GetRandomNum(19,46)+Math.random();
			  var longitude = this.GetRandomNum(85,127)+Math.random();
			  var a={
				   "markers":{
					"latitude": latitude,
					"longitude": longitude,
					"iconPath": "/static/img/onselect.png",
					"width": 32,
					"height":32,
					"id": i,
					"title":"广州市设备",
					"name": "广州市设备", 
					"address": "广州市"
				   }
				}
			  this.Variable.data.push(a)
			}
			for(let i=0;i<this.Variable.data.length;i++){	
			  await this.getRegeo(this.Variable.data[i])
			  }
			var endTime = +new Date();
			console.log("定位"+(endTime-beginTime)+"ms");
			/*
			模拟数据结束，包括getRegeo和GetRandomNum方法在正式使用时都需要在处理或者去除
			*/
		},
		 async onReady() {
			  //初始加载计算标记合并情况
				var mapdata=null
				var buffer_obj={}
				var beginTime = +new Date();
				this.canvas_map=new Canvasmap()
				//首次渲染的id，免去了对每个设备计算距离（增加效率2）
				mapdata=this.canvas_map.init_mapdata(JSON.stringify(this.Variable.data),this.on_id,this.scale)
				this.equipMentname=mapdata.equipMentdata.markers.name
				this.latitude= mapdata.equipMentdata.markers.latitude
				this.longitude= mapdata.equipMentdata.markers.longitude
				  if(mapdata.markers.quantity>1){
						 buffer_obj={}
						 buffer_obj.key_id=mapdata.markers.id
						 buffer_obj.quantity=mapdata.markers.quantity
						 this.markers_id.push(buffer_obj)
						 await this.draw(mapdata.markers.quantity,mapdata.markers.id).then(res=>{
							  if(res){
								 mapdata.markers.iconPath=res
							  }
						  }) 
				   }
				var endTime = +new Date();
			    this.markers.push(mapdata.markers)
			    console.log('标记数量'+this.Variable.data.length,"初始化合并分裂用时共计"+(endTime-beginTime)+"ms");
		  },
		methods: {
			//根据经纬度获取位置
			getRegeo(data){
				return new Promise((resolve, reject) => {
					  this.myAmapFun = new amapFile.AMapWX({key:'0ac92fa7d5fe9244fa0139b16a3a2c21'});
					  this.myAmapFun.getRegeo({
						location:''+data.markers.longitude+','+data.markers.latitude,
						success: (data)=>{
							let province=data[0].regeocodeData.addressComponent
							let province_index=this.province.findIndex(item=>item.markers.name==province.province)
							if(province_index!=-1){
							this.province[province_index].markers.quantity++
							let city_index=this.province[province_index].city.findIndex(item=>item.markers.name==province.city)
								if(city_index>-1){ 
									this.province[province_index].city[city_index].markers.quantity++
								}else{
									this.province[province_index].city.push({
									"markers":{
										"latitude": data[0].latitude,
										"longitude": data[0].longitude,
										"iconPath": "/static/img/onselect.png",
										"width": 32,
										"height":32, 
										"quantity":1, 
										"id": province.adcode,
										"title":province.city+"设备",
										"name": province.city,
										"address":province.city
									   }})
								}
							}
							resolve(this.province)
						}, 
						fail: function(info){ 
						  console.log(info) 
						}
					  })
				});
			},
			//随机生成坐标
			GetRandomNum(Min,Max){   
			    var Range = Max - Min;   
			    var Rand = Math.random();
			    return(Min + Math.round(Rand * Range));   
			},
			//绘制合并标记数量 
			draw(num,id){
				var that=this
				return new Promise((resolve, reject) => {
					var ctx = uni.createCanvasContext('myCanvas', this);
					ctx.draw() 
					ctx.drawImage('../../static/64.png', 0, 0,uni.upx2px(40), uni.upx2px(40)) // drawImage(图片路径,x,y,绘制图像的宽度，绘制图像的高度)
					ctx.setFontSize(uni.upx2px(28)) 
					ctx.setFillStyle('#000000') 
					ctx.fillText(num, uni.upx2px(15), uni.upx2px(28)); 
					ctx.draw(true,(ret)=>{ 
						uni.canvasToTempFilePath({   
							canvasId: 'myCanvas',
							quality: 1, 
							complete: function(res) {
								that.saveFile(res.tempFilePath,id).then(res=>{
										resolve(res)
								})  
							} ,
						})
					}); 	 
				});
			},
			//清除缓存的临时文件
			rmfile(path){
				return new Promise((resolve, reject)=>{
				uni.removeSavedFile({
				  filePath: path,
				  complete: function (res) {
					if(res.errMsg=="removeSavedFile:ok"){
						resolve('ok')
					}
				  } 
				})
				}) 
			},
			//获取地图可视经纬度范围，对不在视野范围内的标记去除（提升效率3）
			getRegion(map,list){
				let mapsection_data=[]
				return new Promise((resolve, reject)=>{
					map.getRegion ({
						success(res) {
							let N_longitude=res.northeast.longitude
							let N_latitude=res.northeast.latitude
							let S_longitude=res.southwest.longitude
							let S_latitude=res.southwest.latitude
							for(let i=0;i<list.length;i++){
								if(list[i].markers.longitude<N_longitude&&list[i].markers.latitude<N_latitude&&list[i].markers.longitude>S_longitude&&list[i].markers.latitude>S_latitude){
									mapsection_data.push(list[i])
								}
							}
							resolve(mapsection_data)
						}
					}) 
				})
			},
			//保存canvas画布的临时文件
			saveFile(tempFilePath,id){
				var that=this
				return new Promise((resolve, reject)=>{
					uni.saveFile({
					  tempFilePath: tempFilePath, 
					  success:(res)=>{
						  for(let i=0;i<this.markers_id.length;i++){
							  if(this.markers_id[i].key_id==id){
								this.markers_id[i].path=res.savedFilePath//将id对应临时存储路径存储
							  }
						  }
						resolve(res.savedFilePath)
					  },
					  fail(err) {
						reject(0)
					  }
					});
				})
			},
			//改变缩放级别时计算标记合并情况
			async regionchange(){
				var mapdata=null
				let map = uni.createMapContext('map');
				var mapsection_data=await this.getRegion(map,this.Variable.data)
				 map.getScale({
					success: async res => {
						 var beginTime = +new Date();  
							 this.map_scale=res.scale 
							 //缩放级别在市级以下，使用设备数量来进行定位计算
							 if(this.map_scale>9||this.map_scale==9){
								 mapdata=this.canvas_map.regionchange_distance(mapsection_data,res.scale)
							 }else if(this.map_scale>6&&this.map_scale<9){//缩放级别达到市级，使用后台返回的当前市级标记数量，当前为模拟数据
								 let markers=[]
								 for(let i=0;i<this.province.length;i++){
									 if(this.province[i].city.length>0){
										 for(let g=0;g<this.province[i].city.length;g++){
											 markers.push(this.province[i].city[g].markers)
										 }
									 }
								 }
								 mapdata={}
								 mapdata.markers=markers
							 }else if(this.map_scale>4&&this.map_scale<6){//缩放级别达到省级，使用后台返回的当前省级标记数量，当前为模拟数据
								let markers=[]
								for(let i=0;i<this.province.length;i++){
									if(this.province[i].markers.quantity>0){
										markers.push(this.province[i].markers)
									}
								}
							    mapdata={}
								mapdata.markers=markers 
							 }else{//缩放级别达到全国范围，使用后台返回的全国标记数量，当前为模拟数据
								let markers=[]
								let quantity=0
								for(let i=0;i<this.province.length;i++){
									if(this.province[i].markers.quantity>0){
										quantity=quantity+this.province[i].markers.quantity
									}
								}
								markers.push({
									"latitude": 29.56667,
									"longitude": 106.45000,
									"iconPath": "/static/img/onselect.png",
									"width": 32,
									"height": 32,
									"quantity": quantity,
									"id": 0,
									"title": "大庆市设备",
									"name": "大庆市",
									"address": "大庆市"
								})
							    mapdata={}
								mapdata.markers=markers 
							 }
							for(let i=0;i<mapdata.markers.length;i++){
								//对比最新标记和存储的标记数据进行对比是否为重复标记
							  let diff_id=this.markers_id.findIndex(item=>item.key_id==mapdata.markers[i].id)
							  if(mapdata.markers[i].quantity>1){
								  //判断之前有存在过这个计数标记但是数据被改变了，那么从新渲染这个标记（提升效率4）
								 if(diff_id!=-1&&this.markers_id[diff_id].quantity!=mapdata.markers[i].quantity){
									 this.markers_id[diff_id].quantity=mapdata.markers[i].quantity
									 await this.rmfile(this.markers_id[diff_id].path)
									 await this.draw(mapdata.markers[i].quantity,this.markers_id[diff_id].key_id).then(res=>{
									   if(res){  
										mapdata.markers[i].iconPath=res 
									   }
									 })
									 //如果之前没有存在过这个标记那么直接push新路径
								 }else if(diff_id==-1){  
									 this.markers_id.push({
										 'key_id':mapdata.markers[i].id,
										 'quantity':mapdata.markers[i].quantity
									 })
									 await this.draw(mapdata.markers[i].quantity,mapdata.markers[i].id).then(res=>{
									   if(res){
										mapdata.markers[i].iconPath=res
									   } 
									 })
									  //否则直接复用
								 }else{
									mapdata.markers[i].iconPath=this.markers_id[diff_id].path
								 } 
							   }else{
								  mapdata.markers[i].iconPath="/static/img/onselect.png"
							  }
							} 
							 var endTime = +new Date();
							  this.markers=mapdata.markers
							  console.log('标记数量'+this.Variable.data.length,"缩放合并分裂用时共计"+(endTime-beginTime)+"ms");
					 },
					 fail: (data, code) => {
						   console.log('fail' + JSON.stringify(data));
					 }
			   })
			},
			//标记点击
			makertap(e) {
			   var id = e.detail.markerId;
			   this.showMarkerInfo(id);
			   this.changeMarkerColor(id);
			 },
			 showMarkerInfo(i){
				 var on_markerindex= this.list.findIndex(item=>item.markers.id==i)
				   this.latitude= this.list[on_markerindex].latitude
				   this.longitude= this.list[on_markerindex].longitude
			   }, 
			   asyncData(data){
				   if(data){
					  this.latitude= data.latitude
					  this.longitude= data.longitude
					  this.map_state = false
					  this.$nextTick(() => (this.map_state = true))
					  this.changeMarkerColor(data.id); 
				   }
			   },
			   //标记点击是更换icon
			   changeMarkerColor(i){
			     for(var j = 0; j < this.markers.length; j++){
			       if(this.markers[j].id==i){
			         this.markers[j].iconPath = "/static/img/select.png"; //如：..­/..­/img/marker_checked.png
					 this.equipMentname=this.markers[j].name
			       }else{
			         this.markers[j].iconPath = "/static/img/onselect.png"; //如：..­/..­/img/marker.png
			       }
			     } 
			   } 
		  }
		}
</script>

<style>
	@import url("./index.css");
</style>
